.TH std::unwrap_reference,std::unwrap_ref_decay 3 "2024.06.10" "http://cppreference.com" "C++ Standard Libary"
.SH NAME
std::unwrap_reference,std::unwrap_ref_decay \- std::unwrap_reference,std::unwrap_ref_decay

.SH Synopsis
   Defined in header <type_traits>
   Defined in header <functional>
   template< class T >             \fB(1)\fP \fI(since C++20)\fP
   struct unwrap_reference;
   template< class T >             \fB(2)\fP \fI(since C++20)\fP
   struct unwrap_ref_decay;

   1) If T is std::reference_wrapper<U> for some type U, provides a member type alias
   type that names U&; otherwise, provides a member type alias type that names T.
   2) If T is std::reference_wrapper<U> for some type U, ignoring cv-qualification and
   referenceness, provides a member type alias type that names U&; otherwise, provides
   a member type alias type that names std::decay_t<T>.

   If the program adds specializations for any of the templates described on this page,
   the behavior is undefined.

.SH Member types

   Name Definition
        \fB(1)\fP U& if T is std::reference_wrapper<U>; T otherwise
   type \fB(2)\fP U& if std::decay_t<T> is std::reference_wrapper<U>; std::decay_t<T>
        otherwise

.SH Helper types

   template<class T>                                     \fB(1)\fP \fI(since C++20)\fP
   using unwrap_reference_t = unwrap_reference<T>::type;
   template<class T>                                     \fB(2)\fP \fI(since C++20)\fP
   using unwrap_ref_decay_t = unwrap_ref_decay<T>::type;

.SH Possible implementation

   template<class T>
   struct unwrap_reference { using type = T; };
   template<class U>
   struct unwrap_reference<std::reference_wrapper<U>> { using type = U&; };

   template<class T>
   struct unwrap_ref_decay : std::unwrap_reference<std::decay_t<T>> {};

.SH Notes

   std::unwrap_ref_decay performs the same transformation as used by std::make_pair and
   std::make_tuple.

    Feature-test macro   Value    Std                       Feature
   __cpp_lib_unwrap_ref 201811L (C++20) std::unwrap_ref_decay and std::unwrap_reference

.SH Example


// Run this code

 #include <cassert>
 #include <functional>
 #include <iostream>
 #include <type_traits>

 int main()
 {
     static_assert(std::is_same_v<std::unwrap_reference_t<int>, int>);
     static_assert(std::is_same_v<std::unwrap_reference_t<const int>, const int>);
     static_assert(std::is_same_v<std::unwrap_reference_t<int&>, int&>);
     static_assert(std::is_same_v<std::unwrap_reference_t<int&&>, int&&>);
     static_assert(std::is_same_v<std::unwrap_reference_t<int*>, int*>);

     {
         using T = std::reference_wrapper<int>;
         using X = std::unwrap_reference_t<T>;
         static_assert(std::is_same_v<X, int&>);
     }
     {
         using T = std::reference_wrapper<int&>;
         using X = std::unwrap_reference_t<T>;
         static_assert(std::is_same_v<X, int&>);
     }

     static_assert(std::is_same_v<std::unwrap_ref_decay_t<int>, int>);
     static_assert(std::is_same_v<std::unwrap_ref_decay_t<const int>, int>);
     static_assert(std::is_same_v<std::unwrap_ref_decay_t<const int&>, int>);

     {
         using T = std::reference_wrapper<int&&>;
         using X = std::unwrap_ref_decay_t<T>;
         static_assert(std::is_same_v<X, int&>);
     }

     {
         auto reset = []<typename T>(T&& z)
         {
         //  x = 0; // Error: does not work if T is reference_wrapper<>
             // converts T&& into T& for ordinary types
             // converts T&& into U& for reference_wrapper<U>
             decltype(auto) r = std::unwrap_reference_t<T>(z);
             std::cout << "r: " << r << '\\n';
             r = 0; // OK, r has reference type
         };

         int x = 1;
         reset(x);
         assert(x == 0);

         int y = 2;
         reset(std::ref(y));
         assert(y == 0);
     }
 }

.SH Output:

 r: 1
 r: 2

.SH See also

   reference_wrapper CopyConstructible and CopyAssignable reference wrapper
   \fI(C++11)\fP           \fI(class template)\fP
   make_pair         creates a pair object of type, defined by the argument types
                     \fI(function template)\fP
   make_tuple        creates a tuple object of the type defined by the argument types
   \fI(C++11)\fP           \fI(function template)\fP
